package com.telrob.bytevm.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.telrob.bytevm.compile.Instruct;
/***
 * 文件加载工具类
 * @author wh
 *
 */
public class ToolUtils {
	
	
	public static int parseNum(String numStr) {
		int number;
		if(numStr.endsWith("B")||numStr.endsWith("b")) {
			numStr=numStr.replace("B", "").replace("b", "");
			number=Integer.parseInt(numStr, 2);
		}else if(numStr.endsWith("H")||numStr.endsWith("h")) {
			numStr=numStr.replace("H", "").replace("h", "");
			number=Integer.parseInt(numStr, 16);
		}else {
			number=Integer.parseInt(numStr, 10);
		}
		return number;
	}
	/**
	 * 
	 * @return
	 */
	public static List<Instruct> register(){
		List<String> classList=scalePackage("com.telrob.bytevm.instruct");
		if(classList!=null&&classList.size()>0) {
			List<Instruct> classLists=new ArrayList<Instruct>();
			for(String className:classList) {
				try {
					Class<?> cls=Class.forName(className);
					Instruct obj=(Instruct)cls.newInstance();
					classLists.add(obj);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return classLists;
		}
		
		
		return null;
	}
	
	/**
	 * 扫描指定目录下的jar包
	 * @param pkg
	 * @return
	 */
	public static List<String> scalePackage(String pkg) {
		String pkgm=pkg.replace(".", "/");
		URL url = ToolUtils.class.getResource("/"+pkgm);
		String packages=ToolUtils.class.getPackage().getName();
		packages=packages.replace(".", "/");
    	String protocol = url.getProtocol();
    	String file=url.getPath();
    	if(protocol!=null&&protocol.equals("file")) {
    		file=file.substring(1, file.length());
    		File fl=new File(file);
    		String[]ddd=fl.list();
    		if(ddd!=null&&ddd.length>0) {
    			List<String>names=new ArrayList<String>();
    			for(String d:ddd) {
    				String name=(pkg+"."+d).replace(".class", "");
    				names.add(name);
    			}
    			return names;
    		}
    	}else if(protocol!=null&&protocol.equals("jar")) {
    		try {
				JarURLConnection connect=(JarURLConnection)(url.openConnection());
				JarFile jarFile=connect.getJarFile();
				Enumeration<JarEntry> entries=jarFile.entries();
				if(entries!=null) {
					List<String>names=new ArrayList<String>();
					while(entries.hasMoreElements()) {
						JarEntry ele=entries.nextElement();
						String name=ele.getName();
						if(!ele.isDirectory()&&name.startsWith(pkgm)) {
							name=name.replace(".class", "").replace("/", ".");
							names.add(name);
						}
					}
					return names;
				}
    		} catch (Exception e) {
				e.printStackTrace();
			}
    	}
    	
    	return null;
	}
	
	/***
	 * 获取一字节
	 * @param data
	 * @param offset
	 * @return
	 */
	public static byte getByte(byte[]data,int offset) {
		return data[offset];
	}
	
	/***
	 * 获取两字节 ,低字节放低地址
	 * @param data
	 * @param offset
	 * @return
	 */
	public static short getShort(byte[]data,int offset) {
		return (short)(((data[offset+1]&0xFF)<<8)|(data[offset]&0xFF));
	}
	
	/***
	 * 获取四字节
	 * @param data
	 * @param offset
	 * @return
	 */
	public static int getInt(byte[]data,int offset) {
		return (int)((data[offset+3]&0xFF)<<24)|((data[offset+2]&0xFF)<<16)|((data[offset+1]&0xFF)<<8)|(data[offset]&0xFF);
	}
	
	/***
	 * 读取文件，并转换成byte数组
	 * @param fileName 文件名称
	 * @return
	 */
	public static byte[] loadFile(String fileName) {
		FileInputStream fin=null;
		ByteArrayOutputStream bout=null;
		try {
			bout=new ByteArrayOutputStream();
			fin=new FileInputStream(fileName);
			byte[]bb=new byte[1024*10];
			int len=0;
			while((len=fin.read(bb))>0) {
				bout.write(bb,0,len);
			}
			return bout.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(fin!=null) {
				try {
					fin.close();
				} catch (IOException e) {
				}
			}
			if(bout!=null) {
				try {
					bout.close();
				} catch (IOException e) {
				}
			}
		}
		return null;
	}
	
	public static byte[] int2bytes(int num) {
		byte[]bb=new byte[4];
		bb[0]=(byte)(0xFF&(num>>0));
		bb[1]=(byte)(0xFF&(num>>8));
		bb[2]=(byte)(0xFF&(num>>16));
		bb[3]=(byte)(0xFF&(num>>24));
		return bb;
	}
	
}
